/*
 * Copyright 2017 Zhihu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.zhihu.matisse.internal.utils;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;

import androidx.core.content.FileProvider;
import androidx.core.os.EnvironmentCompat;
import androidx.fragment.app.Fragment;

import com.zhihu.matisse.internal.entity.CaptureStrategy;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.List;

public class MediaStoreCompat {

    private final WeakReference<Activity> mContext;
    private final WeakReference<Fragment> mFragment;
    private       CaptureStrategy         mCaptureStrategy;
    private       Uri                     mCurrentPhotoUri;
    private       String                  mCurrentPhotoPath;
    private String defaultPath;

    public MediaStoreCompat(Activity activity) {
        mContext = new WeakReference<>(activity);
        mFragment = null;
    }

    public MediaStoreCompat(Activity activity, Fragment fragment) {
        mContext = new WeakReference<>(activity);
        mFragment = new WeakReference<>(fragment);
    }

    /**
     * Checks whether the device has a camera feature or not.
     *
     * @param context a context to check for camera feature.
     * @return true if the device has a camera feature. false otherwise.
     */
    public static boolean hasCameraFeature(Context context) {
        PackageManager pm = context.getApplicationContext().getPackageManager();
        return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
    }

    public void setCaptureStrategy(CaptureStrategy strategy) {
        mCaptureStrategy = strategy;
    }

    public void dispatchCaptureIntent(Context context, int requestCode) {
        Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (captureIntent.resolveActivity(context.getPackageManager()) != null) {
            try {
                //file可以创建在沙盒内部或者外部
                File photoFile = createImageFile();
                if (photoFile != null) {
                    mCurrentPhotoPath = photoFile.getAbsolutePath();
                    mCurrentPhotoUri = createImageUri(photoFile);
                }else {
                    System.out.println("photoFile=========为空");
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("e========="+e);
            }

            System.out.println("mCurrentPhotoPath========"+mCurrentPhotoPath);
            System.out.println("mCurrentPhotoUri========"+mCurrentPhotoUri);
            captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCurrentPhotoUri);
            captureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                List<ResolveInfo> resInfoList = context.getPackageManager()
                        .queryIntentActivities(captureIntent, PackageManager.MATCH_DEFAULT_ONLY);
                for (ResolveInfo resolveInfo : resInfoList) {
                    String packageName = resolveInfo.activityInfo.packageName;
                    context.grantUriPermission(packageName, mCurrentPhotoUri,
                            Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                }
            }

            if (mFragment != null) {
                mFragment.get().startActivityForResult(captureIntent, requestCode);
            } else {
                mContext.get().startActivityForResult(captureIntent, requestCode);
            }
        }
    }

    /**
     * 创建图片地址uri,用于保存拍照后的照片 Android 10以后使用这种方法
     * @return 图片的uri
     */
    private Uri createImageUri(File photoFile) {
        Uri uri = null;
        //兼容Android Q和以下版本
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            if (mCaptureStrategy.isPublic) {
                //设置保存参数到ContentValues中
                ContentValues contentValues = new ContentValues();
                //设置文件名
                contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, System.currentTimeMillis()+"");
                //android Q中不再使用DATA字段，而用RELATIVE_PATH代替
                //TODO RELATIVE_PATH是相对路径不是绝对路径;
//            System.out.println("absPath-------->"+photoFile.getAbsolutePath());
//            System.out.println("parent-------->"+photoFile.getParent());
//            System.out.println("path-------->"+photoFile.getPath());
                System.out.println("path2222-------->"+Environment.DIRECTORY_PICTURES+"/" + mCaptureStrategy.directory);
                contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES+"/" + mCaptureStrategy.directory);
                //设置文件类型
                contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/JPEG");
                //执行insert操作，向系统文件夹中添加文件
                //EXTERNAL_CONTENT_URI代表外部存储器，该值不变
                //例(外部存储)：content://media/external/images/media/27158
                uri = mContext.get().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
            } else {
                //例(内部存储)：content://com.zhihu.matisse.sample.fileprovider/my_images/Android/data/com.zhihu.matisse.sample/files/Pictures/myZhiHu/1632903377753.jpg
                uri = FileProvider.getUriForFile(mContext.get(), mCaptureStrategy.authority, photoFile);
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //例(外部存储)：content://com.zhihu.matisse.sample.fileprovider/my_images/myZhiHu/1632896197539.jpg
            //例(内部存储)：content://com.zhihu.matisse.sample.fileprovider/my_images/Android/data/com.zhihu.matisse.sample/files/Pictures/myZhiHu/1632903377753.jpg
            uri = FileProvider.getUriForFile(mContext.get(), mCaptureStrategy.authority, photoFile);
        } else {
            //例(外部存储)：file:///storage/emulated/0/Pictures/myZhiHu/1632895659352.jpg
            //例(内部存储)：file:///storage/emulated/0/Android/data/com.zhihu.matisse.sample/files/Pictures/myZhiHu/1632904352740.jpg
            uri = Uri.fromFile(photoFile);
        }
        System.out.println("uri-------->"+uri);
        return uri;

    }

    @SuppressWarnings("ResultOfMethodCallIgnored")
    private File createImageFile() {
        // 创建文件名
        String imageFileName = String.format("%s.jpg", System.currentTimeMillis());
        File storageDir;
        //设置根目录
        if (mCaptureStrategy.isPublic) {//图片存在公共区域defaultPath下
            storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
            if (!storageDir.exists()) storageDir.mkdirs();
        } else {//图片存到沙盒内
            storageDir = mContext.get().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        }
        //设置图片直接上级目录
        if (mCaptureStrategy.directory != null) {
            storageDir = new File(storageDir, mCaptureStrategy.directory);
            if (!storageDir.exists()) storageDir.mkdirs();
        }
        //创建图片
        File tempFile = new File(storageDir, imageFileName);

        System.out.println("tempFile----->"+tempFile);
        // 处理用户的外部存储未准备好的情况
        if (!Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(tempFile))) {
            return null;
        }

        return tempFile;
    }

    public Uri getCurrentPhotoUri() {
        return mCurrentPhotoUri;
    }

    public String getCurrentPhotoPath() {
        return mCurrentPhotoPath;
    }

    public void setDefaultPath(String defaultPath) {
        this.defaultPath = defaultPath;
    }
}
